import { checkPermi, checkRole } from '@/utils/auth'
/**
 * 判断是否已为方法注入权限认证
 * @param method
 * @returns {boolean}
 */
const hasInjected = (method) => method.toString().indexOf('// --auth-inject') !== -1

const hasRole = {
  inserted(el, binding, vnode) {
    const check = binding.value
    if (!check) { // 权限标识为空不控制
      return false
    }
    const instance = vnode.context
    const $auth = instance.$auth
    if (!$auth || !$auth(check, 'role')) {
      el.parentNode && el.parentNode.removeChild(el)
    }
  }
}

const hasPermi = {
  inserted(el, binding, vnode) {
    vnode.context.$nextTick(() => {
      const check = binding.value
      if (!check) { // 权限标识为空不控制
        return false
      }
      const instance = vnode.context
      const $auth = instance.$auth
      if (!$auth || !$auth(check, 'permi')) {
        el.parentNode && el.parentNode.removeChild(el)
      }
    })
  }
}

const AuthorityPlugin = {
  install(Vue) {
    Vue.directive('hasRole', hasRole) // 角色权限
    Vue.directive('hasPermi', hasPermi)// 权限字符串
    Vue.mixin({
      beforeCreate() {
        if (this.$options.auth) {
          const auth = this.$options.auth
          Object.keys(auth).forEach(key => {
            if (this.$options.methods[key]) {
              const method = this.$options.methods[key]
              if (!hasInjected(method)) {
                let authConfig = auth[key]
                authConfig = (typeof authConfig === 'string') ? { check: authConfig } : authConfig
                const { check, type, onFailure } = authConfig
                this.$options.methods[key] = function() {
                  // --auth-inject
                  if (this.$auth(check, type)) {
                    return method.apply(this, arguments)
                  } else {
                    if (onFailure && typeof onFailure === 'function') {
                      this[`$${check}Failure`] = onFailure
                      return this[`$${check}Failure`](check)
                    } else {
                      this.$message.error(`对不起，您没有操作权限：${check}`)
                    }
                    return 0
                  }
                }
              }
            }
          })
        }
      },
      methods: {
        /**
         * 操作权限校验
         * @param check 需要校验的操作名
         * @param type 校验类型，通过 permission 校验，还是通过 role 校验。
         * 如未设置，则自动识别，如匹配到当前路由 permission 则 type = permission，否则 type = role
         * @returns {boolean} 是否校验通过
         */
        $auth(check, type) {
          if (type === 'permi') {
            return checkPermi(check)
          } else if (type === 'role') {
            return checkRole(check)
          } else {
            return checkPermi(check) || checkRole(check)
          }
        }
      }
    })
  }
}

export default AuthorityPlugin
